#include "HerzeleidPrecompiled.hxx"
#include "HerzeleidStateCore.hxx"

using namespace HerzeleidRendererStatesNamespaceImpl;

HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::BindStageIADeferred( // Binds the input assembler set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3, // Context to bind input assembler set to
	_In_ InputAssemblerSwapSetConstPtrConst pState, // Input assembler set to bind
	_In_opt_ UInt32 uiVertexBufferStartSlot, // Vertex buffer index to start binding from 
	_In_opt_ UInt32 uiVertexBufferNumSlots // Num vertex buffers to bind 
	)
{
	pContext3->IASetVertexBuffers(uiVertexBufferStartSlot, uiVertexBufferNumSlots, pState->VertexBufferArray, pState->VertexStrideArray, pState->VertexOffsetArray);
	pContext3->IASetIndexBuffer(pState->IndexBuffer, pState->eIndexBufferFormat, pState->IndexBufferOffset);
	pContext3->IASetPrimitiveTopology(pState->eTopology);
	pContext3->IASetInputLayout(pState->InputLayout);
}
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::BindStageOMWithUAVsDeferred( // Binds the output merger set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3, // Context to bind output merger set to
	_In_ OutputMergerSwapSetConstPtrConst pState // Output merger set to bind
	)
{
	pContext3->OMSetDepthStencilState(pState->DepthStencilState, pState->StencilRef);
	pContext3->OMSetBlendState(pState->BlendState, reinterpret_cast<Float32ConstPtr>(&pState->BlendFactor), pState->SampleMask);
	pContext3->OMSetRenderTargetsAndUnorderedAccessViews(
		HERZELEID_RTV_NUM_SLOTS, pState->RenderTargetViewArray, pState->DepthStencilView, 0, HERZELEID_UAV_NUM_SLOTS, 
		pState->UnorderedAccessViewArray, pState->UnorderedAccessViewInitialCountArray
		);
}
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::BindStageOMDeferred( // Binds the output merger set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3, // Context to bind output merger set to
	_In_ OutputMergerSwapSetConstPtrConst pState // Output merger set to bind
	)
{
	pContext3->OMSetDepthStencilState(pState->DepthStencilState, pState->StencilRef);
	pContext3->OMSetBlendState(pState->BlendState, reinterpret_cast<Float32ConstPtr>(&pState->BlendFactor), pState->SampleMask);
	pContext3->OMSetRenderTargets( HERZELEID_RTV_NUM_SLOTS, pState->RenderTargetViewArray, pState->DepthStencilView );
}
HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::BindStageRSDeferred( // Binds the rasterizer set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3,  // Context to bind rasterizer set to
	_In_ RasterizerSwapSetConstPtrConst pState // Rasterizer set to bind
	)
{
	pContext3->RSSetScissorRects(HERZELEID_VIEWPORT_NUM_SLOTS, pState->ScissorRectArray);
	pContext3->RSSetViewports(HERZELEID_VIEWPORT_NUM_SLOTS, pState->ViewportArray);
	pContext3->RSSetState(pState->RasterizerState);
}

HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::UnbindStageIADeferred( // Binds the input assembler set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3   // Context to bind input assembler set to
	)
{
	const static InputAssemblerSwapSet NullContent;
	pContext3->IASetVertexBuffers(0u, HERZELEID_VERTEX_BUFFER_NUM_SLOTS, NullContent.VertexBufferArray, NullContent.VertexStrideArray, NullContent.VertexOffsetArray);
	pContext3->IASetIndexBuffer(NullContent.IndexBuffer, NullContent.eIndexBufferFormat, NullContent.IndexBufferOffset);
	pContext3->IASetPrimitiveTopology(NullContent.eTopology);
	pContext3->IASetInputLayout(NullContent.InputLayout);
}

HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::UnbindStageOMWithUAVsDeferred( // Binds the output merger set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3	// Context to bind output merger set to
	)
{
	const static OutputMergerSwapSet NullContent;
	pContext3->OMSetDepthStencilState(NullContent.DepthStencilState, NullContent.StencilRef);
	pContext3->OMSetBlendState(NullContent.BlendState, reinterpret_cast<Float32ConstPtr>(&NullContent.BlendFactor), NullContent.SampleMask);
	pContext3->OMSetRenderTargetsAndUnorderedAccessViews(
		HERZELEID_RTV_NUM_SLOTS, NullContent.RenderTargetViewArray, NullContent.DepthStencilView, 0, HERZELEID_UAV_NUM_SLOTS, 
		NullContent.UnorderedAccessViewArray, NullContent.UnorderedAccessViewInitialCountArray
		);
}

HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::UnbindStageOMDeferred( // Binds the output merger set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3	// Context to bind output merger set to
	)
{
	const static OutputMergerSwapSet NullContent;
	pContext3->OMSetDepthStencilState(NullContent.DepthStencilState, NullContent.StencilRef);
	pContext3->OMSetBlendState(NullContent.BlendState, reinterpret_cast<Float32ConstPtr>(&NullContent.BlendFactor), NullContent.SampleMask);
	pContext3->OMSetRenderTargets( HERZELEID_RTV_NUM_SLOTS, NullContent.RenderTargetViewArray, NullContent.DepthStencilView );
}

HERZELEID_FORCEINLINING HERZELEID_NOALIAS Void HerzeleidRendererStatesNamespaceImpl::UnbindStageRSDeferred( // Binds the rasterizer set to the rendering pipeline 
	_In_ NativeDeferredContext3PtrConst pContext3	// Context to bind rasterizer set to
	)
{
	const static RasterizerSwapSet NullContent;
	pContext3->RSSetScissorRects(HERZELEID_VIEWPORT_NUM_SLOTS, NullContent.ScissorRectArray);
	pContext3->RSSetViewports(HERZELEID_VIEWPORT_NUM_SLOTS, NullContent.ViewportArray);
	pContext3->RSSetState(NullContent.RasterizerState);
}